package com.adlotto2.lcdns.cronos.asynctask;

import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.app.Dialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import com.adlotto2.lcdns.cronos.http.CNHttpManager;
import com.adlotto2.lcdns.cronos.http.CNHttpResponse;
import com.adlotto2.lcdns.util.CNCronosLog;

public class CNDataAsyncTask extends AsyncTask<String, Integer, CNHttpResponse.SimpleHttpResponse> {
	public static final int ERROR_CODE_FAIL = 2;
	public static final int ERROR_CODE_CALCEL = 3;
	public static final int ERROR_CODE_NO_CONNECTION = 4;
	public static final int ERROR_CODE_BAD_REQUEST = 5;
	public static final int ERROR_CODE_SERVERERROR = 6;
	public static final int ERROR_CODE_AUTH_EXPIRE = 7;
	public static final int ERROR_CODE_BREAK = 8;
	public static final int ERROR_CODE_PARSING_ERROR = 9;
	private Context mContext = null;
	private Dialog mLoadingDialog = null;
	private int mHttpMethod = 2;
	private CNDataAsyncTaskCallback mCallback = null;
	private String mUrl = null;

	private HashMap<String, String> mPersistParams = null;

	public CNDataAsyncTask(Context context, int method,
			CNDataAsyncTaskCallback callback, Dialog loadingDialog) {
		this.mContext = context;
		this.mLoadingDialog = loadingDialog;
		this.mHttpMethod = method;
		this.mCallback = callback;
	}

	public CNDataAsyncTask(Context context, int method,
			CNDataAsyncTaskCallback callback) {
		this(context, method, callback, null);
	}

	public CNDataAsyncTask(Context context,
			CNDataAsyncTaskCallback callback, Dialog loadingDialog) {
		this(context, 2, callback, loadingDialog);
	}

	public CNDataAsyncTask(Context context,
			CNDataAsyncTaskCallback callback) {
		this(context, 2, callback, null);
	}

	protected void onPreExecute() {
		if (this.mCallback != null) {
			this.mCallback.onAsyncPreRequest();
			this.mUrl = this.mCallback.onGetAsyncRequestUrl();
		}

		if (this.mLoadingDialog != null) {
			this.mLoadingDialog.show();
		}
	}

	protected void onCancelled() {
		if (this.mLoadingDialog != null) {
			this.mLoadingDialog.cancel();
		}

		if (this.mCallback != null) {
			this.mCallback.onAsyncCancelRequest();
		}
	}
	
	protected CNHttpResponse.SimpleHttpResponse doInBackground(String[] params) {
		Log.d("BenTag","doinbackground");
		if ((this.mCallback != null) && (this.mUrl != null)) {

			return CNHttpManager.getInstance().requestData(this.mContext, this.mHttpMethod, this.mUrl, null);
		} else {
			return null;
		}
	}

	protected void onPostExecute(CNHttpResponse.SimpleHttpResponse httpResponse) {
		if (httpResponse != null) {
//			if (CNCronosLog.isDebugLevel()) {
				CNCronosLog.d("HttpStatusCode: " + httpResponse.getHttpStatusCode());
//				CNCronosLog.d("HttpStatusCode: " + httpResponse.getHttpStatusCode());
				CNCronosLog.d("HttpResponseBody: " + httpResponse.getHttpResponseBodyAsString());
				Log.i("BenTag", "HttpStatus Code : " + httpResponse.getHttpStatusCode());
//			}

			if (httpResponse.getHttpStatusCode() == 200) {
				
				try {
					DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
					DocumentBuilder beilder = factory.newDocumentBuilder();
					
					Document doc = beilder.parse(httpResponse.getHttpResponseBodyAsInputStream());
					Element xmlObject = doc.getDocumentElement();
					
					//NodeList resultNode = xmlElement.getElementsByTagName("result");
					
					NodeList rcodeNode = xmlObject.getElementsByTagName("rcode");
					String rcode = rcodeNode.item(0).getFirstChild().getNodeValue();
					Log.i("BenTag", "Received Rcode : " + rcode);
					CNCronosLog.d("rcode: " + rcode);
					
					//NodeList rdataNode = xmlObject.getElementsByTagName("rdata");

					if ("RET0000".equals(rcode)) {
						if (this.mCallback == null)
						{
							dialogDismiss();
							return;
						}
						this.mCallback.onAsyncRequestCompleted(xmlObject);
						{
							dialogDismiss();
							return;
						}
					}
					
					if (this.mCallback != null){
						
						NodeList rmsgNode = xmlObject.getElementsByTagName("rmsg");
						String rmsg = "";
						try {
							rmsg = rmsgNode.item(0).getFirstChild().getNodeValue();
						} catch(Exception e) {
							e.printStackTrace();
							rmsg = "";
						}
						CNCronosLog.d("rmsg: " + rmsg);
						this.mCallback.onAsyncDataError(xmlObject, rmsg);
						
						dialogDismiss();
						return;
					}
					
				} catch (Exception e) {
					if (CNCronosLog.isErrorLevel()) {
						CNCronosLog.e("CNDataAsyncTask Exception",e);
					}
					this.mCallback.onAsyncRequestError(ERROR_CODE_PARSING_ERROR);
					if (this.mCallback == null)
					{
						dialogDismiss();
						return;
					}
				}				
			} else if (httpResponse.getHttpStatusCode() == 10000) {
				if (this.mCallback != null) {
					this.mCallback.onAsyncRequestError(ERROR_CODE_NO_CONNECTION);
				}
			} else if ((httpResponse.getHttpStatusCode() == 400)
					|| (httpResponse.getHttpStatusCode() == 404)) {
				if (this.mCallback != null) {
					this.mCallback.onAsyncRequestError(ERROR_CODE_BAD_REQUEST);
				}
			} else if (httpResponse.getHttpStatusCode() == 500) {
				if (this.mCallback != null) {
					this.mCallback.onAsyncRequestError(ERROR_CODE_SERVERERROR);
				}
			} else if (httpResponse.getHttpStatusCode() == 10002) {
				if (this.mCallback != null) {
					this.mCallback.onAsyncRequestError(ERROR_CODE_AUTH_EXPIRE);
				}

			} else if (this.mCallback != null) {
				this.mCallback.onAsyncRequestError(ERROR_CODE_SERVERERROR);
			}

		} else if (this.mCallback != null) {
			this.mCallback.onAsyncRequestError(ERROR_CODE_SERVERERROR);
		}

	}
	
	protected void dialogDismiss() {
		if (this.mLoadingDialog != null) {
			this.mLoadingDialog.dismiss();
		}
	}

	public void addPersistParams(String name, String value) {
		if (this.mPersistParams == null) {
			this.mPersistParams = new HashMap();
		}

		this.mPersistParams.put(name, value);
	}

	public String getPersisitParam(String name) {
		if (this.mPersistParams != null) {
			return (String) this.mPersistParams.get(name);
		}

		return null;
	}

	public int getPersisParamCount() {
		if (this.mPersistParams != null) {
			return this.mPersistParams.size();
		}

		return 0;
	}

	public static abstract interface CNDataAsyncTaskCallback {
		public abstract void onAsyncPreRequest();

		public abstract void onAsyncRequestCompleted(Element xmlObject);

		public abstract void onAsyncCancelRequest();

		public abstract String onGetAsyncRequestUrl();

		public abstract void onAsyncRequestError(int paramInt);

		public abstract void onAsyncDataError(Element paramXMLObject, String paramString);
	}
}